﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Windows;
using Esponce.QRCode;
using Esponce.Common;

namespace Esponce.Models
{
	public class MainViewModel : INotifyPropertyChanged
	{
		#region Constructor
		public MainViewModel()
		{
			this.ApiKey = Settings.ApiKey;
			RefreshMethodList();
		}
		#endregion

		#region Public properties
		public string ApiKey
		{
			get
			{
				return this.apiKey;
			}
			set
			{
				if (this.apiKey != value)
				{
					this.apiKey = value;
					OnPropertyChanged("ApiKey");
				}
			}
		}
		private string apiKey;

		public bool UseSSL
		{
			get
			{
				return this.SelectedCertificateState == CertificateState.HTTPS;
			}
			set
			{
				this.SelectedCertificateState = (value ? CertificateState.HTTPS : CertificateState.HTTP);
			}
		}

		public ObservableCollection<SelectListItem> ServiceMethodList
		{
			get
			{
				return this.serviceMethodList;
			}
			set
			{
				if (this.serviceMethodList != value)
				{
					this.serviceMethodList = value;
					OnPropertyChanged("ServiceMethodList");
				}
			}
		}
		private ObservableCollection<SelectListItem> serviceMethodList;

		public SelectListItem SelectedServiceMethod
		{
			get
			{
				return this.selectedServiceMethod;
			}
			set
			{
				if (this.selectedServiceMethod != value)
				{
					this.selectedServiceMethod = value;
					if (value != null)
					{
						CreateView(value.ViewType);
					}
					OnPropertyChanged("SelectedServiceMethod");
				}
			}
		}
		private SelectListItem selectedServiceMethod;

		public IEnumerable<ApiFormat> DataFormatList
		{
			get
			{
				yield return ApiFormat.Json;
				yield return ApiFormat.Xml;
			}
		}

		public ApiFormat SelectedDataFormat
		{
			get
			{
				return this.selectedDataFormat;
			}
			set
			{
				if (this.selectedDataFormat != value)
				{
					this.selectedDataFormat = value;
					OnPropertyChanged("SelectedDataFormat");
				}
			}
		}
		private ApiFormat selectedDataFormat;

		public IEnumerable<CertificateState> CertificateStateList
		{
			get
			{
				yield return CertificateState.HTTPS;
				yield return CertificateState.HTTP;
			}
		}

		public CertificateState SelectedCertificateState
		{
			get
			{
				return this.selectedCertificateState;
			}
			set
			{
				if (this.selectedCertificateState != value)
				{
					this.selectedCertificateState = value;
					OnPropertyChanged("SelectedCertificateState");
					OnPropertyChanged("UseSSL");
				}
			}
		}
		private CertificateState selectedCertificateState;

		public FrameworkElement View
		{
			get
			{
				return this.view;
			}
			set
			{
				if (this.view != value)
				{
					this.view = value;
					OnPropertyChanged("View");
				}
			}
		}
		private FrameworkElement view;
		#endregion

		#region Protected methods
		protected void CreateView(Type viewType)
		{
			try
			{
				if (models == null)
				{
					models = new Dictionary<Type, object>();
				}

				//Save previous model with all entered parameters
				if (this.View != null && this.View.DataContext != null)
				{
					Type previousType = this.View.GetType();
					if (models.ContainsKey(previousType))
					{
						models[previousType] = this.View.DataContext;
					}
					else
					{
						models.Add(previousType, this.View.DataContext);
					}
				}

				//Create a new view
				this.View = Activator.CreateInstance(viewType) as FrameworkElement;

				//Restore last used ViewModel
				object model = models.ContainsKey(viewType) ? models[viewType] : null;
				if (model != null)
				{
					this.View.DataContext = model;
				}
			}
			catch
			{
				this.View = null;
			}
		}

		private Dictionary<Type, object> models = null;

		protected void RefreshMethodList()
		{
			this.ServiceMethodList = new ObservableCollection<SelectListItem>()
			{
				new SelectListItem() { Name = "generate", ViewType = typeof(Views.GenerateView) },
				new SelectListItem() { Name = "decode", ViewType = typeof(Views.DecodeView) },
				new SelectListItem() { Name = "track/list", ViewType = typeof(Views.TrackListView) },
				new SelectListItem() { Name = "track/campaign", ViewType = typeof(Views.TrackCampaignView) },
				new SelectListItem() { Name = "track/qrcode", ViewType = typeof(Views.TrackQRCodeView) },
				new SelectListItem() { Name = "track/statistics", ViewType = typeof(Views.TrackStatisticsView) },
				new SelectListItem() { Name = "track/export", ViewType = typeof(Views.TrackExportView) },
				new SelectListItem() { Name = "track/import", ViewType = typeof(Views.TrackImportView) },
			};
			this.SelectedServiceMethod = this.ServiceMethodList.First();
		}
		#endregion

		#region Public methods
		public QRCodeClient CreateClient()
		{
			var client = new QRCodeClient();
			client.UseSSL = this.UseSSL;
			client.ApiKey = this.ApiKey;
			client.Format = this.SelectedDataFormat;
			client.ApplicationName = "EsponceAPIDemo/" + typeof(App).Assembly.GetName().Version;
			Settings.ApiKey = this.ApiKey;
			return client;
		}
		#endregion

		#region INotifyPropertyChanged Members
		public event PropertyChangedEventHandler PropertyChanged;
		protected virtual void OnPropertyChanged(string propertyName)
		{
			if (PropertyChanged != null)
			{
				PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
			}
		}
		#endregion
	}
}
